# author:       李皓
# email:        133465202@qq.com
# repository:   https://gitee.com/ButchQiuQiu/
"""
文件服务
"""
import os

import Param


def getFiles(root_path):
    """
    获得目录root_path下（包括各级子目录）所有java文件的路径
    """
    file_list = []
    for i in os.listdir(root_path):
        path = root_path + "\\" + i
        if os.path.isfile(path):
            file_list.append(path)
        elif os.path.isdir(path):
            files = getFiles(path)
            for f in files:
                if f[::-1].find("avaj.") != -1:
                    file_list.append(f)
    return file_list


def findColumnCommentByJavaFiles(propertyName: str, pathList: list):
    """
    从java文件中获取字段的注释
    :param propertyName:  字段名, 小驼峰
    :param pathList:    路径列表,优先级从先到后, 如果0路径找到了字段和注释.后面的path不再查询
    :return: 注释
    """
    for path in pathList:
        text: str = open(path, 'r', encoding='utf-8').read()
        if findFirstStrByList(text, " " + propertyName + ";", " " + propertyName + " ", " " + propertyName + "=") != -1:
            text = text[:text.find(" " + propertyName)]
            text = text[::-1]
            text = text[text.find("/*") + 2:text.find("**/")]
            text = text[::-1]
            text = text.replace("/", "").replace("*", "").replace("\n", "").replace(" ", "")
            return text
    return None


def buildComponentDict(text: str, path: str):
    """
    获取组件
    :param text:    文件内容
    :param path:    文件路径
    :return:
    """
    # 获取类名
    className = path[::-1]
    className = className[className.find(".") + 1:className.find("\\")]
    className = className[::-1]
    if className.find("Abstract") != -1:
        className = className[8:]
    # 初始化组件节点
    if "component" not in Param.runDict.keys():
        Param.runDict["component"] = {}
    # 如果有组件注解,构建字典
    if "@Embeddable" in text or "@MappedSuperclass" in text:
        # 初始化对应节点------------------------------------------------
        if className not in Param.runDict["component"].keys():
            Param.runDict["component"][className] = {}
        # 如果对应路径没有的的情况下才能赋值------------------------
        if "@Embeddable" in text and "mainClass" not in Param.runDict["component"][className].keys():
            Param.runDict["component"][className]["mainClass"] = path
        elif "@MappedSuperclass" in text and "superClass" not in Param.runDict["component"][className].keys():
            Param.runDict["component"][className]["superClass"] = path


def findCommentByComponent(propertyName: str, pathList: list) -> str:
    """
    尝试匹配组件并且生成注释
    :param propertyName:  字段名, 小驼峰
    :param pathList:    路径列表,优先级从先到后, 如果0路径找到了字段和注释.后面的path不再查询
    :return: 注释
    """
    # 最终注释
    finalComment: str = None
    propertyTempName = propertyName
    while len(propertyTempName) > 0 and finalComment is None:
        for path in pathList:
            sourceText: str = open(path, 'r', encoding='utf-8').read()
            text = "".join(sourceText)
            if text.find(" " + propertyTempName) != -1:
                text = text[:text.find(" " + propertyTempName)]
                text = text[::-1]
                text = text[text.find("/*") + 2:text.find("**/")]
                text = text[::-1]
                text = text.replace("/", "").replace("*", "").replace("\n", "").replace(" ", "")
                # 组件归属的注释
                finalComment = "".join(text)
                # 开始匹配组件注释
                text = sourceText[:sourceText.find(" " + propertyTempName)]
                text = text[::-1]
                text = text[:findFirstStrByList(text, "etavirp", "detcetorp")]
                componentClassName = text[::-1].strip()
                componentPropertyName = propertyName[len(propertyTempName):]
                componentPropertyName = componentPropertyName[0:1].lower() + componentPropertyName[1:]
                # 判断是否有component, class节点
                if "component" in Param.runDict.keys() and componentClassName in  Param.runDict["component"].keys():
                    componentComment:str=findColumnCommentByJavaFiles(componentPropertyName,
                                                 Param.runDict["component"][componentClassName].values())
                    if componentComment is not None:
                        return finalComment + componentComment
                break
        propertyTempName = propertyTempName[:-1]
    return finalComment


def findFirstStrByList(text: str, *args) -> str:
    """
    搜索字符串, 多个参数. 返回最近的一个. 如果一个都没找到那就返回-1
    :param text:
    :param args:
    :return:
    """
    findIndexList: list = []
    for findStr in args:
        if text.find(findStr) != -1:
            findIndexList.append(text.find(findStr))
    if len(findIndexList) > 0:
        return min(findIndexList)
    else:
        return -1
